
#include <stdexcept>

#include "autocall-util.h"
#include "symdb-conf.h"
#include "database.h"
#include "string-util.h"

using std::runtime_error;

namespace {

sqlite3 *g_db_conn_ptr = NULL;
void close_db_conn()
{
    if (g_db_conn_ptr != NULL)
        sqlite3_close_v2(g_db_conn_ptr);
    return ;
}
AUTOCALL(close_db_conn);

}

sqlite3 *database_connection()
{
    if (g_db_conn_ptr == NULL) {
        auto &conf = SymdbConf::instance();
        std::string database_path {conf.dbPath()};
        int open_ret = sqlite3_open(database_path.c_str(),&g_db_conn_ptr);
        if (open_ret != SQLITE_OK) {
            throw std::runtime_error(format("sqlite3_open(%s):%s",
                                            database_path.c_str(),
                                            sqlite3_errmsg(g_db_conn_ptr)));
        }
    }
    return g_db_conn_ptr;
}

void exec_sql(sqlite3 *db,const char *sql_stmt_str)
{
    char *err_msg_ptr = NULL;
    AUTOCALL_FUNC(destroy_err_msg) {
        if (err_msg_ptr != NULL)
            sqlite3_free(err_msg_ptr);
    };
    AUTOCALL(destroy_err_msg);

    int exec_ret = sqlite3_exec(db,sql_stmt_str,NULL,NULL,&err_msg_ptr);
    if (exec_ret != SQLITE_OK) {
        throw std::runtime_error(format("执行 SQL 语句 %s 出错;错误提示: %s",
                                        sql_stmt_str,
                                        err_msg_ptr));
    }
    return ;
}

std::string to_sqlite_str(const char *src)
{
    char *res = sqlite3_mprintf("%q",src);
    if (res == NULL)
        throw runtime_error(format("%s(%s):error",__PRETTY_FUNCTION__,src));
    std::string str_res { res };
    sqlite3_free(res);
    return str_res;
}
